package oop.core.ai;


import java.util.Random;


import oop.core.area.DamageAreaEffect;
import oop.core.entity.NPC;
import oop.core.map.GameMap;
import oop.core.map.Location;
import oop.core.med.NPCMovementMediator;

/**
 * AI superclass controls NPC movement
 */
public abstract class AI {
	private NPCMovementMediator movementMediator;
	private GameMap gameMap;
	private NPC npc;
	
	/**
	 * AI constructor.
	 * @param movementMediator
	 * @param gameMap
	 * @param npc
	 */
	protected AI(NPCMovementMediator movementMediator, GameMap gameMap, NPC npc){
		this.movementMediator = movementMediator;
		this.gameMap = gameMap;
		this.npc = npc;
	}
	
	/**
	 * Subtypes must implement move to move the AI.
	 */
	public abstract void move();
	
	/**
	 * A general move algorithm that makes a random movement.
	 */
	public void randomMove(){
		Random randGen = new Random();
		int direction = 5;
		while(direction == 5 || direction == 0){
			direction = randGen.nextInt(10);
		}
		if(!checkFuturePosition(direction))
			getMovementMediator().moveEntity(direction);
	}
	
	/**
	 * Checks a potential new location for damaging afea affects.
	 * @param direction
	 * @return
	 */
	public boolean checkFuturePosition(int direction){
    	Location futureLoc = npc.getLoc();
    	switch(direction){
    		case 1:  futureLoc = Location.add(futureLoc, new Location(-1,-1));
    		case 2:  futureLoc = Location.add(futureLoc, new Location(0,-1));
    		case 3:  futureLoc = Location.add(futureLoc, new Location(1,-1));
    		case 4:  futureLoc = Location.add(futureLoc, new Location(-1,0));
    		case 6:  futureLoc = Location.add(futureLoc, new Location(1,0));
    		case 7:  futureLoc = Location.add(futureLoc, new Location(-1,1));
    		case 8:  futureLoc = Location.add(futureLoc, new Location(0,1));
    		case 9:  futureLoc = Location.add(futureLoc, new Location(1,1));
    		default: futureLoc = Location.add(futureLoc, new Location(0,0));
    	}
    	return gameMap.getAreaEffectAt(futureLoc) instanceof DamageAreaEffect;	// I'm so sorry Dave!
    }
	
	/**
	 * get/set methods
	 */
	public NPCMovementMediator getMovementMediator() {
		return movementMediator;
	}

	public void setMovementMediator(NPCMovementMediator movementMediator) {
		this.movementMediator = movementMediator;
	}

	public GameMap getMap() {
		return gameMap;
	}

	public void setMap(GameMap gameMap) {
		this.gameMap = gameMap;
	}

	public GameMap getGameMap() {
		return gameMap;
	}

	public void setGameMap(GameMap gameMap) {
		this.gameMap = gameMap;
	}

	public NPC getNpc() {
		return npc;
	}

	public void setNpc(NPC npc) {
		this.npc = npc;
	}
}
